package test.model;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

public class ContactDAO {
	public static String getPath(){
		String path;
		String decodedPath;
		try {
			path = ContactDAO.class.getProtectionDomain().getCodeSource().getLocation().getPath();
			decodedPath = URLDecoder.decode(path, "UTF-8");
			System.out.println("ImagePath: " + decodedPath);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			decodedPath = ClassLoader.getSystemClassLoader().getResource(".").getPath();
			System.out.println("Alternative ImagePath: " + decodedPath);
		}
		
		return decodedPath;
		//String path = ClassLoader.getSystemClassLoader().getResource(".").getPath();
	}
	
	public static void copyFileUsingFileStreams(File source, File dest) throws IOException {
		InputStream input = null;
	    OutputStream output = null;
	    try {
	        input = new FileInputStream(source);
	        output = new FileOutputStream(dest);
	        byte[] buf = new byte[1024];
	        int bytesRead;
	        while ((bytesRead = input.read(buf)) > 0)
	        	output.write(buf, 0, bytesRead);
	    } finally {
	        input.close();
	        output.close();
	    }
	}

	
	public ArrayList<ContactItem> loadAllItems()throws IOException{
		ArrayList<ContactItem> result = new ArrayList<ContactItem>();
		RandomAccessFile raf = null;
		ContactItem item;
		int len, addr = 0, byteRead=0;
		byte[] buf = new byte[256];
		//
		try{
			raf = new RandomAccessFile(new File(getPath() + "data/data.dat"), "r");
			
			while(raf.getFilePointer()<raf.length()){
				item = new ContactItem();
				
				//read total item length
				int itemLength = raf.readShort();
				
				boolean isDeleted = raf.readByte()==1?true:false;
				if(!isDeleted){
					//read length of name, 1 byte
					len = raf.readByte();
					byteRead = raf.read(buf, 0, len);
					String name = new String(buf, 0, len, Charset.forName("utf-8"));
					
					//read phone number 24
					len = raf.readByte();
					byteRead = raf.read(buf, 0, len);
					String phone = new String(buf, 0, len);
					
					//read imagePath
					len = raf.readByte();
					byteRead = raf.read(buf, 0, len);
					String image = new String(buf, 0, len);
					System.out.println("Image: " + image);
					
					item.setName(name);
					item.setPhone(phone);
					item.setImage(image);
					item.setAddress(addr);
					result.add(item);
				}else
					raf.seek(addr + itemLength);
					
				addr += itemLength;
			}
		}catch(IOException ex){
			if(raf != null)
				raf.close();
		}

		return result;
	}
	
	public boolean addContact(ContactItem item) throws IOException{
		RandomAccessFile raf = null;
		File file = new File(getPath() + "data/data.dat");
		if(!file.exists())
            file.createNewFile();
        try {
			raf = new RandomAccessFile(file, "rw");
			raf.seek(raf.length());
			
			item.setAddress(raf.length());
			
			byte[] bufName = item.getName().getBytes("utf-8");
			byte[] bufPhone = item.getPhone().getBytes();
			byte[] bufImage = item.getImage().getBytes();
			
			//2 byte for item length
			//1 byte for name length
			//1 byte for phone length
			//1 byte for imagePath length
			//1 byte to indicate this item is deleted
			int len = 6 + bufName.length + bufPhone.length + bufImage.length;
			
			raf.writeShort(len);
			
			//write delete flag
			raf.writeByte(0);
			
			//write name
			raf.writeByte(bufName.length);
			raf.write(bufName, 0, bufName.length);
			
			//write phone number
			raf.writeByte(bufPhone.length);
			raf.write(bufPhone, 0, bufPhone.length);
			
			//write imagePath
			raf.writeByte(bufImage.length);
			raf.write(bufImage, 0, bufImage.length);
			return true;
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
        finally{
        	if(raf != null)
        		raf.close();
        }
		
	}
	
	public boolean deleteContact(ContactItem item)throws IOException{
		return false;
	}
	
	public boolean updateContact(ContactItem item)throws IOException{
		RandomAccessFile raf = null;
		File file = new File(getPath() + "data/data.dat");
        try {
			raf = new RandomAccessFile(file, "rw");
			
			byte[] bufName = item.getName().getBytes("utf-8");
			byte[] bufPhone = item.getPhone().getBytes();
			byte[] bufImage = item.getImage().getBytes();
			int newlen = 6 + bufName.length + bufPhone.length + bufImage.length;
			
			raf.seek(item.getAddress());
			int oldlen = raf.readShort();
			
			if(newlen>oldlen){
				raf.seek(item.getAddress()+2);
				raf.writeByte(1);
				
				raf.seek(raf.length());
				
				item.setAddress(raf.length());
				
				raf.writeShort(newlen);
				
				//write delete flag
				raf.writeByte(0);
				
				//write name
				raf.writeByte(bufName.length);
				raf.write(bufName, 0, bufName.length);
				
				//write phone number
				raf.writeByte(bufPhone.length);
				raf.write(bufPhone, 0, bufPhone.length);
				
				//write imagePath
				raf.writeByte(bufImage.length);
				raf.write(bufImage, 0, bufImage.length);
			}else{
				raf.seek(item.getAddress()+2);
				
				//item.setAddress(raf.getFilePointer());
				//raf.writeShort(newlen);
				
				//write delete flag
				raf.writeByte(0);
				//write name
				raf.writeByte(bufName.length);
				raf.write(bufName, 0, bufName.length);
				//write phone number
				raf.writeByte(bufPhone.length);
				raf.write(bufPhone, 0, bufPhone.length);
				//write imagePath
				raf.writeByte(bufImage.length);
				raf.write(bufImage, 0, bufImage.length);
			}
			
			return true;
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}finally{
        	if(raf != null)
        		raf.close();
        }
		
	}
}
